package com.jh.concurrent.threadpool;

import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author JH_Wong
 * @projectName newforward
 * @title ForkJoinDemo.java
 * @package com.jh.concurrent.threadpool
 * @description Fork/Join例子
 * @date 2019-05-28 16:22
 */
public class ForkJoinDemo {

    private ForkJoinPool forkJoinPool;

    public ForkJoinDemo() {
        forkJoinPool = new ForkJoinPool();
    }

    private final class SumTask extends RecursiveTask<Long>{

        private long[] numbers;
        private int from;
        private int to;

        public SumTask(long[] numbers, int from, int to) {
            this.numbers = numbers;
            this.from = from;
            this.to = to;
        }

        @Override
        protected Long compute() {
            if (to - from < 6) {
                AtomicLong total = new AtomicLong(0);
                Arrays.stream(numbers).forEach(tmp -> {
                    total.addAndGet(tmp);
                });
                return total.get();
            } else {
                int middle = (from + to) / 2;
                SumTask taskLeft = new SumTask(numbers, from, middle);
                SumTask taskRight = new SumTask(numbers, middle+1, to);
                taskLeft.fork();
                taskRight.fork();
                return taskLeft.join() + taskRight.join();
            }
        }
    }

    public Long sum(long[] numbers){
        return forkJoinPool.invoke(new SumTask(numbers, 0, numbers.length-1));
    }

    public static void main(String[] args) throws InterruptedException {
        ForkJoinDemo demo = new ForkJoinDemo();
        long[] arrays = new long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L};
        Long result = demo.sum(arrays);
        System.out.println("结果：" + result);
    }

}
